package tools

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"mime/multipart"
	"os"
	"path"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	. "github.com/hunterhug/go_image"
)

type SingleUploadImage struct{}

// 存储上传路径
var storeUploadPath string = "./static/upload_images/"

/**
 * 上传单张图片
 *
 * @param *gin.Context ctx --------------------------------------------必传
 * @param *multipart.FileHeader image ---------------------------------必传
 * @param []map[string]string thumbs ----------------------------------必传
 * @param map[string]string water -------------------------------------必传
 * @return map[string]interface{}, error
 * @author huwl
 */
func (s *SingleUploadImage) SingleUploadImage(ctx *gin.Context, image *multipart.FileHeader, thumbs []map[string]string, water map[string]string) (map[string]interface{}, error) {
	imageExt := path.Ext(image.Filename)
	allowExtMap := map[string]bool{
		".jpg":  true,
		".png":  true,
		".gif":  true,
		".jepg": true,
	}

	if !allowExtMap[imageExt] {
		return nil, errors.New("图片类型错误仅支持jpg/png/gif/jepg")
	}

	filepath := storeUploadPath + GetDay()
	err := os.MkdirAll(filepath, 0755)
	if err != nil {
		return nil, errors.New("创建目录失败")
	}

	filename := strconv.FormatInt(GetUnix(), 10)
	h := md5.New()
	h.Write([]byte(filename)) // 需要加密的字符串
	filename = hex.EncodeToString(h.Sum(nil)) + imageExt
	imagePath := filepath + "/" + filename

	// 上传文件到指定的路径
	err = ctx.SaveUploadedFile(image, imagePath)
	if err != nil {
		return nil, errors.New("上传图片失败")
	}

	thumbUrls := []map[string]string{}
	if len(thumbs) > 0 {
		for _, thumb := range thumbs {
			imageUrl := filepath + "/thumb-" + thumb["width"] + "X" + thumb["height"] + filename
			width, _ := strconv.Atoi(thumb["width"])
			height, _ := strconv.Atoi(thumb["height"])
			err = ThumbnailF2F(imagePath, imageUrl, width, height)
			if err != nil {
				return nil, err
			}

			thumbUrl := map[string]string{}
			thumbUrl["image_url"] = strings.TrimLeft(imageUrl, ".")
			thumbUrl["absolute_image_url"] = UploadImageDomain + strings.TrimLeft(imageUrl, ".")

			thumbUrls = append(thumbUrls, thumbUrl)
		}
	}

	return map[string]interface{}{
		"image_url":          strings.TrimLeft(imagePath, "."),
		"absolute_image_url": UploadImageDomain + strings.TrimLeft(imagePath, "."),
		"thumb_urls":         thumbUrls,
	}, nil
}

/**
 * 批量图片上传
 *
 * @param *gin.Context ctx --------------------------------------------必传
 * @param []*multipart.FileHeader images ------------------------------必传
 * @return map[string]interface{}, error
 * @author huwl
 */
func (s *SingleUploadImage) BatchUploadImage(ctx *gin.Context, images []*multipart.FileHeader) (map[string]interface{}, error) {
	imagesUrl := []string{}
	for _, image := range images {
		imageExt := path.Ext(image.Filename)
		allowExtMap := map[string]bool{
			".jpg":  true,
			".png":  true,
			".gif":  true,
			".jepg": true,
		}

		if !allowExtMap[imageExt] {
			return nil, errors.New("图片类型错误仅支持jpg/png/gif/jepg")
		}

		filepath := storeUploadPath + GetDay()
		err := os.MkdirAll(filepath, 0755)
		if err != nil {
			return nil, errors.New("创建目录错误")
		}

		//获取微秒数
		var filename = strconv.FormatInt(GetUnixNano(), 10)
		var h = md5.New()
		h.Write([]byte(filename)) // 需要加密的字符串
		filename = hex.EncodeToString(h.Sum(nil)) + imageExt
		filepath = filepath + "/" + filename

		// 上传文件到指定的路径
		err = ctx.SaveUploadedFile(image, filepath)
		if err != nil {
			return nil, errors.New("上传图片失败")
		}

		imagesUrl = append(imagesUrl, strings.TrimLeft(filepath, "."))
	}

	return map[string]interface{}{
		"image_urls": imagesUrl,
	}, nil
}
